import argparse
import multiprocessing
import time
from datetime import datetime, timedelta

import pydevd_pycharm
import uvicorn
from fastapi import FastAPI, BackgroundTasks
from starlette.middleware.cors import CORSMiddleware
from xbase_util.es_db_util import EsDb

from global_ver import es_req, common_logger
from src.bean.CircleTaskBean import CircleTaskBean
from src.bean.ExportCsvBean import ExportCsvBean
from src.bean.TrafficDetailBean import TrafficDetailBean
from src.queue.capture import start_capture_queue
from src.queue.predict import start_predict_queue
from src.queue.save import start_save_queue
from src.util.api_get_detail import get_traffic_detail
from src.util.set_label import set_label_task

parser = argparse.ArgumentParser(description="参数")
parser.add_argument('--debug', action='store_true', help='是否用调试模式')
args = parser.parse_args()

if args.debug:
    pydevd_pycharm.settrace("10.255.76.63", port=8005, stdoutToServer=True, stderrToServer=True)
    common_logger.info("调试模式已启用")
else:
    common_logger.info("非调试模式")


def start_get_session_queue(bean: CircleTaskBean, capture_queue):
    if bean.start_time is None:
        start_time = datetime.now() - timedelta(minutes=bean.time_before_now_m)
    else:
        if "-" in bean.start_time:
            start_time = datetime.strptime(bean.start_time, "%Y-%m-%d %H:%M:%S")
        else:
            start_time = datetime.strptime(bean.start_time, "%Y/%m/%d %H:%M:%S")
    while True:
        endTime = start_time + timedelta(seconds=bean.time_span_s)
        capture_queue.put((start_time, endTime, bean.exp, bean.scene))
        time.sleep(bean.sleep_s)
        start_time = endTime


if __name__ == '__main__':
    app = FastAPI()
    manager = multiprocessing.Manager()
    shared_dict = manager.dict()
    capture_queue = multiprocessing.Queue()
    save_queue = multiprocessing.Queue()
    predict_queue = multiprocessing.Queue()
    esdb = EsDb(es_req, manager)


    @app.post("/auto_predict",
              description="start_time和exp可以不传，start_time不传则用过去time_before_now_m分钟的时间；exp不传则用配置文件的表达式和数据分割方式，数据分割方式(在配置文件中split_by)有none,size,protocol；none不分割数据，即将获取的数据直接灌入模型,size按照包、字节大小分割数据给到模型,protocol则按照协议分割数据给到模型，其中protocol方式因为normal场景没有相关协议，则使用的是size的方式")
    def auto_predict(bean: CircleTaskBean, task: BackgroundTasks):
        task.add_task(start_get_session_queue, bean, capture_queue)
        return {"message": "开始定时添加队列", "code": 200, "data": {"queue": capture_queue.qsize()}}


    @app.post("/export_es_data_to_csv", description="导出预测后的csv文件")
    def export_es_data_to_csv(bean: ExportCsvBean, task: BackgroundTasks):
        task.add_task(set_label_task, bean, common_logger)
        return {"code": 200, "message": "已开始任务", "data": None}


    @app.post("/get_traffic_detail", description="获取流量详情数据")
    def export_es_data_to_csv(bean: TrafficDetailBean):
        return get_traffic_detail(bean, common_logger)


    multiprocessing.Process(target=start_save_queue, args=(save_queue,)).start()
    multiprocessing.Process(target=start_predict_queue, args=(predict_queue, save_queue, shared_dict,)).start()
    multiprocessing.Process(target=start_capture_queue, args=(capture_queue, predict_queue, manager,)).start()
    app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"],
                       allow_headers=["*"])
    uvicorn.run(app, host="0.0.0.0", port=9090)
